package contegor.scire.core;

import java.net.InetAddress;
import java.net.UnknownHostException;


/**
 * Defines a transaction. 
 * Only through a {@link Transaction} {@link TaskId}s can be created.
 * Is not thread safe, but {@link Transaction}s should not be shared between threads.
 *
 * @version $Revision$
 * @author  Héctor Cirbián Pousa ($Author$)
 */
@Version("$Id$")
public class Transaction {

  private static String clientName;
  static {
    try {
      clientName = InetAddress.getLocalHost().getHostName();
    }
    catch(UnknownHostException ex) {
      clientName = "unknown";
    }
  }

  private static ThreadLocal<Transaction> current = new ThreadLocal<Transaction>();

  /**
   * Sets the 'client name' that will be used in all subsequent transactions.
   */
  public static void setClientName(String name) {
    clientName = name;
  }

  /**
   * Sets the current transaction. Only not auto-commit transactions allowed.
   * 
   * @throws IllegalArgumentException if an auto-commit transaction is passed.
   */
  public static void setCurrent(Transaction transaction) {
    if (transaction.isAutocommit())
      throw new IllegalArgumentException("Autocommit transactions not allowed.");
    current.set(transaction);
  }

  public static Transaction getCurrent() {
    return current.get();
  }


  private TaskId taskId;

  public Transaction(boolean autocommit) {
    this.taskId = new TaskId(new TransactionId(clientName, autocommit));
  }

  public TransactionId getTransactionId() {
    return this.taskId.getTransactionId();
  }

  public boolean isAutocommit() {
    return this.getTransactionId().isAutocommit();
  }

  public TaskId nextTaskId() {
    if (this.isAutocommit()) {
      this.getTransactionId().generateNumber();
      return (this.taskId = new TaskId(this.getTransactionId()));
    }
    else
      return (this.taskId = this.taskId.next(false)); 
  }
}